package lar.system.network;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.LinkedList;

import lar.system.engine.MainProgram;
import lar.system.network.msgParser.ParsedMessage;
import lar.system.network.msgParser.Strings;

import android.bluetooth.BluetoothSocket;
import android.os.Handler;
import android.util.Log;

public class BluetoothConnection implements Runnable 
{
	private BluetoothSocket sock;
	private InputStream in = null;
    private OutputStream out = null;
    private MessageTokenizer<String> tokenizer;
    private LinkedList<String> Q = new LinkedList<String>();
    
    
	public BluetoothConnection(BluetoothSocket socket)
	{
		this.sock = socket;
		tokenizer = new FixedSeparatorMessageTokenizer("\n", Charset.forName("UTF-8"));
		try 
		{
			in = socket.getInputStream();
			out = socket.getOutputStream();
		} 
		catch (IOException e) 
		{
			e.printStackTrace();
			MainProgram.MessageBox("Failed to initialize connection");
			close();
		}

	}
	
	public void run() 
	{
		byte[] buffer = new byte[1024];  // buffer store for the stream
        int bytes; 
        // Keep listening to the InputStream until an exception occurs
        while (sock.isConnected()) 
        {
            try 
            {
                // Read from the InputStream
                Log.d("R", "reading");
            	bytes = in.read(buffer, 0, 1024);
            	//Log.d("R", "read: " + (new String(buffer, 0, bytes)));
                if(bytes < 0) close();
                else 
                {
                	tokenizer.addBytes(buffer, bytes);
                	while(tokenizer.hasMessage())
                    {
                    	String msg = tokenizer.nextMessage();
                    	synchronized(Q) { Q.add(msg); }
                    }
                }
                
            } catch (IOException e) {
                break;
            }
        }

	}
	
	public boolean hasIncomingMsgs()
	{
		synchronized(Q)
		{
			return !Q.isEmpty();
		}
	}
	
	public String getIncomingMessage()
	{
		synchronized(Q)
		{
			return Q.poll();
		}
	}
	
	public void write(String msg) 
	{
		final String msg2 = msg;// + "\n";
        
    	Handler mainHandler = new Handler(MainProgram.currentActivity.getMainLooper());

    	Runnable myRunnable = new Runnable()
    	{
			public void run() 
			{
				try 
				{
					out.write(msg2.getBytes());
					Log.d("R", "sent data " + msg2);
				} 
				catch (IOException e) 
				{
					close();
		        	MainProgram.MessageBox("Bluetooth write failed");
				}
			}
    	};
    	mainHandler.post(myRunnable);
    	
    	
         
    }

	public synchronized void close()
	{
		try 
		{
			sock.close();
			out.close();
			in.close();
		} catch (IOException e) 
		{
		}
		MainProgram.MessageBox("Socket closed");
	}

}
